<template>
  <a-table 
    v-bind="$attrs" :dataSource="mDataSource" 
    :pagination="mPagination"
    :columns="mColumns"
    @change="handleTableChange"
    >
    <template #[key]="data" v-for="(item, key) in $slots">
      <slot :name="key" v-bind="data || {}"></slot>
    </template>
  </a-table>
</template>
<script setup lang="ts">
import { PropType, onMounted, ref, watch } from 'vue';
import type { PaginationProps,TableColumnType } from 'ant-design-vue';
import request from '/@/utils/request'
import { SorterResult } from 'ant-design-vue/es/table/interface';
// 定义事件
const emits = defineEmits(['change'])
// 定义属性
const props = defineProps({
  api: { // 接口地址或接口函数--->新增属性
    type: [Function, String] as PropType<((param: any)=>Promise<any>) | String>
  },
  pagination: { // 当这里定义了和attrs一样的属性的时候，v-bind="$attrs"就会忽略该属性
    type: Object as PropType<PaginationProps>
  },
  defaultSorter: { // 排序的默认配置--->新增属性
    type: Object as PropType<SorterResult>
  },
  columns: { // 列定义，当这里定义了和attrs一样的属性的时候，v-bind="$attrs"就会忽略该属性
    type: Array as PropType<TableColumnType[]>,
    default() {
      return []
    }
  }
})
// 定义排序对象
const mSorter = ref<SorterResult>({
  order: 'ascend',
  ...props.defaultSorter
})
/**
 * 处理表格列定义数据
 * @param arr 
 */
const handleColumns = (arr: Array<TableColumnType>)=>{
  if(!props.defaultSorter) {
    // 如果默认的排序字段未配置，则使用第一个定义有sorter和defaultSortOrder的列
    const defaultSorterColumn: TableColumnType | undefined = arr?.find(column=>{
      return column.sorter && column.defaultSortOrder
    })
    if(defaultSorterColumn)  {
      mSorter.value = {
        ...mSorter.value,
        field: defaultSorterColumn.key,
        order: defaultSorterColumn.defaultSortOrder
      }
    }
  }
  arr?.forEach(column=>{
    // 处理默认排序
    if(column.key == mSorter.value.field) {
      column.sorter = true
      column.defaultSortOrder = mSorter.value.order || 'ascend'
    } else {
      column.defaultSortOrder = undefined
    }
  })
  return arr
}
// 数据源
const mDataSource = ref([])
// 列定义
const mColumns = ref<Array<TableColumnType>>(handleColumns(props.columns))
// 分页对象定义
const mPagination = ref<PaginationProps>({
  current: 1,
  pageSize: 10,
  total: 0,
  showQuickJumper: true,
  ...props.pagination
})

// 监听分页对象
watch(()=>props.pagination,()=>{
  mPagination.value = {
    ...mPagination.value,
    ...props.pagination
  }
  requestData({})
}, {
  deep: true
})
const requestData = (params: any) => {
  let apiFun: ((param: any)=>Promise<any>) | undefined
  if(props.api && typeof props.api == 'function') {
    apiFun = props.api
  } else if(props.api && typeof props.api == 'string') {
    apiFun = (param: any) => request.post(props.api as any, param)
  }
  if(apiFun) {
    const sorter = mSorter.value
    apiFun({
      pageNum: mPagination.value.current,
      pageSize: mPagination.value.pageSize,
      orderBy: (sorter.order && sorter.field)?`${sorter.field} ${sorter.order.replace('end','')}`:undefined,
      ...params
    }).then((res: any)=>{
      mPagination.value.total = res.data.recordCount || res.data.length
      mDataSource.value = res.data.rows || res.data
    })
  }
}
/**
 * 表格事件处理
 * @param pagination 
 * @param filters 
 * @param sorter 
 */
const handleTableChange = (pagination: PaginationProps,filters: any,sorter: any) => {
  mPagination.value = {
    ...mPagination.value,
    ...pagination
  }
  mSorter.value = {
    ...mSorter.value,
    ...sorter
  }
  emits('change', mPagination.value, filters, mSorter.value)
  requestData({})
}
onMounted(()=>{
  requestData({})
})
</script>
<style lang="less" scoped>

</style>